/**
 * 
 */
package com.app.framework.handler;

import java.net.InetSocketAddress;
import java.util.List;

import org.apache.log4j.Logger;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;

import com.app.framework.context.ActionRequest;
import com.app.framework.context.Context;
import com.app.framework.context.Request;
import com.app.framework.exception.CommunicationException;
import com.app.framework.exception.FrameException;
import com.app.framework.socket.Packet;
import com.app.framework.socket.SocketContext;
import com.app.framework.socket.SocketResponse;
import com.app.framework.socket.client.ServerClient;
import com.app.framework.socket.response.SCResponse;
import com.app.framework.socket.response.SSResponse;
import com.app.framework.socket.sender.Player;
import com.app.framework.socket.sender.Sender;
import com.app.framework.socket.sender.Server;

/**
 * @author lisong
 * @version 2013-2-26 下午2:18:29
 */
public class SocketUpstreamHandler extends GameUpstreamHandler {

	private static final Logger logger = Logger.getLogger(SocketUpstreamHandler.class);
	
	public SocketUpstreamHandler(int type,boolean forClient) {
		super(type,forClient);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {

		List<Packet> pks = (List<Packet>) e.getMessage();
		
		for(int i=0;i<pks.size();i++) {
			
			Packet packet = pks.get(i);
			
			String ip = ((InetSocketAddress)e.getRemoteAddress()).getAddress().getHostAddress();
			
			Request req = new ActionRequest(packet.getContent(),packet.getType(), ip);
			
			SocketResponse<? extends Sender<?>> response = null;
			if(handlerType == HANDLER_TYPE_CS) {
				response = new SCResponse((Player) e.getChannel().getAttachment());
			}
			else {
				response = new SSResponse((Server) e.getChannel().getAttachment());
			}
			
			response.setRequest(req);
			
			Context context = new SocketContext(response);
			
			context.execute();
		
			context.close();
		}
	}
	
	@Override
	public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		Sender<?> sender = null;
		if(handlerType == HANDLER_TYPE_CS) {
			sender = new Player(e.getChannel());
		}
		else if(handlerType == HANDLER_TYPE_SS){
			sender = new Server(e.getChannel());
		}
		 if(sender == null) {
			 throw new CommunicationException("未知的handler type");
		 }
		e.getChannel().setAttachment(sender);
		if(forClient) {
			ServerClient.semaphore.release();
			if(ServerClient.semaphore.availablePermits() > 1) {
				System.err.println("ssssssssssssssssssssssssssss");
			}
		}
		if(logger.isDebugEnabled()) {
			logger.debug("channel open......."+e.getChannel());
		}
	}
	
	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		if(logger.isDebugEnabled()) {
			logger.debug("channel connected......"+e.getChannel());
		}
	}
	
	@Override
	public void channelDisconnected(ChannelHandlerContext ctx,
			ChannelStateEvent e) throws Exception {
		if(logger.isDebugEnabled()) {
			logger.debug("channel disconnected......"+e.getChannel());
		}
		Sender<?> sender = (Sender<?>) e.getChannel().getAttachment();
		sender.disconnect();
	}
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
			throws Exception {
		
		e.getCause().printStackTrace();
		
		logger.error(e.getCause());
		
		if(FrameException.class.isAssignableFrom(e.getCause().getClass())) {//已知异常下发给客户端,未知异常不处理 以免引起死循环(被循环调用该方法)
			try {
				
				FrameException fe = (FrameException)e.getCause();
				
				int code = fe.getCode();
				
//				response.protocolException(code, message);
			} catch (Exception e2) {
				e2.printStackTrace();
				logger.error(e2);
			}
		}
	}
}
